<template>
	<div class="page-making" v-bind="pageStyle">
		<eForm
      v-if="myConfig && myConfig.list"
      ref="pageMakingForm"
      v-bind="formProps"
    >
      <template v-for="item in myConfig.list" :key="item.model">
        <template v-if="isContainerEle(item.type)">
          <component
            :is="getContainerTag(item.type)"
            :key="item.key"
            v-bind="getValidProps(item.options.props)"
          >
            <component
              v-for="col in item.columns"
              :key="col.id"
              :is="getContainerTag(item.type, true)"
              v-bind="getValidProps(col)"
            >
              <PageMakingItem
                v-for="cItem in col.list"
                :ref="(el: any) => itemRefs[cItem.model] = el"
                :key="cItem.id"
                :options="cItem"
                :models="models"
                @update:model="setModels({ [cItem.model]: $event })"
              />
            </component>
          </component>
        </template>
        <PageMakingItem
          v-else
          :ref="(el: any) => itemRefs[item.model] = el"
          :options="item"
          :models="models"
          @update:model="setModels({ [item.model]: $event })"
        />
      </template>
    </eForm>
	</div>

  <Loading v-if="loading" />
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue'
import useConfig from '@/hooks/pageMaking/useConfig'
import useExpose from '@/hooks/pageMaking/useExpose';
import { isContainerEle, getContainerTag, getValidProps } from '@/hooks/pageMaking/useUtil'
import { Form } from 'view-ui-plus'

interface IProps {
	config: any,
  modelValue?: any,
  code?: string
}

const props = withDefaults(defineProps<IProps>(), {
  modelValue: {}
})

const emit = defineEmits<{
	(e: 'update:modelValue', data: Record<string, any>): void
}>()

const pageMakingForm = ref<InstanceType <typeof Form>>()
const itemRefs = reactive<Record<string, any>>({})

const { myConfig, models, itemInfos, loading } = useConfig(props)

watch(
  () => models,
  (newVal) => {
    emit('update:modelValue', newVal)
  },
  {
    deep: true
  }
)

const pageStyle = computed(() => ({
  class: myConfig?.config?._className || '',
  style: myConfig?.config?._style || ''
}))

const formProps = computed(() => {
  const labelPosition = myConfig.config?.labelPosition || 'left'
  return {
    labelPosition,
    labelWidth: labelPosition === 'top' ? null : myConfig.config?.labelWidth || 100,
    model: models
  }
})

function getChildRefByKey(key: string) {
  if (!Object.keys(models).includes(key)) {
    return null
  }
  return itemRefs[key]?.compRef || null
}

function validate() {
  if (pageMakingForm.value) {
    return (pageMakingForm.value as any).validate()
  }
  return new Promise(resolve => resolve(true))
}

function resetFields() {
  if (pageMakingForm.value) {
    return (pageMakingForm.value as any).resetFields()
  }
}

const {
  getModels, setModels,
  updateOptions, showLoading, hideLoading,
  changeDisplayFields, changeDisabledFields
} = useExpose(
  models,
  itemInfos,
  loading
)

defineExpose({
  getModels,
  setModels,
  updateOptions,
  showLoading,
  hideLoading,
  getChildRefByKey,
  changeDisplayFields,
  changeDisabledFields,
  validate,
  resetFields
})

</script>

<style lang="less" scoped></style>
